package com.emm.yixun.website.listeners;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.emm.yixun.common.model.enums.*;
import com.emm.yixun.customer.service.channel.ChannelSendHttpMessageService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import com.emm.yixun.common.enums.ResponseEnums;
import com.emm.yixun.common.model.BusinessAbnorma;
import com.emm.yixun.common.model.NeedReceiveRefund;
import com.emm.yixun.common.model.Signed;
import com.emm.yixun.common.model.Subscribe;
import com.emm.yixun.common.model.SubscribeTrans;
import com.emm.yixun.common.model.TransactionRelation;
import com.emm.yixun.common.model.User;
import com.emm.yixun.common.model.dto.BusinessAbnormaDto;
import com.emm.yixun.common.model.dto.HaveReceiveRefundDto;
import com.emm.yixun.common.model.dto.NeedReceiveRefundDto;
import com.emm.yixun.common.model.dto.NoticeEntity;
import com.emm.yixun.common.model.dto.ProjectRoomDto;
import com.emm.yixun.common.model.dto.RoomChangeHistoryDto;
import com.emm.yixun.common.model.dto.SubscribeDto;
import com.emm.yixun.common.model.dto.SubscribeTransDto;
import com.emm.yixun.common.model.dto.SubscribeTransRequestDto;
import com.emm.yixun.common.model.dto.TransactionRelationDto;
import com.emm.yixun.common.response.Response;
import com.emm.yixun.common.response.ResponseList;
import com.emm.yixun.common.utils.BeanUtil;
import com.emm.yixun.customer.service.SignedServiceFacade;
import com.emm.yixun.customer.service.SubscribeServiceFacade;
import com.emm.yixun.customer.service.SubscribeTransServiceFacade;
import com.emm.yixun.customer.service.TransactionRelationServiceFacade;
import com.emm.yixun.estate.service.ProjectRoomServiceFacade;
import com.emm.yixun.marketing.service.BusinessAbnormaServiceFacade;
import com.emm.yixun.marketing.service.HaveReceiveRefundServiceFacade;
import com.emm.yixun.marketing.service.NeedReceiveRefundServiceFacade;
import com.emm.yixun.marketing.service.RoomChangeHistoryServiceFacade;
import com.emm.yixun.system.service.notice.subscribe.SubscribeChangeHouseNoticeFacade;
import com.emm.yixun.website.common.utils.SpringWebContextUtil;
import com.emm.yixun.website.common.utils.security.ShiroUtil;
import com.emm.yixun.website.service.ActivitiProcessServiceImpl;
import com.emm.yixun.website.service.system.log.ActCommitLogService;
/**
* 类描述： 换房流程审批结果处理
* 创建者： ThinkPad
* 项目名称： emm-website
* 创建时间： 2016年7月12日 下午1:59:03
* 版本号： v1.0
 */
public class BusinessChangeHouseListeners implements Serializable, ExecutionListener{
	private static final long serialVersionUID = -2409351825760552344L;

	@Override
	public void notify(DelegateExecution execution) throws Exception {
		String id=execution.getProcessBusinessKey(); //业务ID
		String processInstanceId=execution.getProcessInstanceId();	//流程ID
		if(getActivitiProcessServiceImpl().isCheckPass(processInstanceId)){
			BusinessAbnormaDto queryBusiness= new BusinessAbnormaDto();
			queryBusiness.setBusinessId(new Long(id));
			queryBusiness.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_1.getNo());
			queryBusiness.setAuditStatus(AuditStatusEnum.AUDIT.getNo()); //只获取审核中的流程信息
			ResponseList<BusinessAbnorma> businessAbnormaList = getbusinessAbnormaServiceFacade().findByDto(queryBusiness);
			if(businessAbnormaList.isSuccess()&&businessAbnormaList.getEntity()!=null&&businessAbnormaList.getEntity().size()>0){
				BusinessAbnorma businessAbnorma = businessAbnormaList.getEntity().get(0);
				boolean flag = checkAuditCommit(businessAbnorma);
				if(!flag) {
					throw new Exception(ResponseEnums.RESPONSEENUMS_999999.getName());
				}
			}
			
			Subscribe scibe = getSubscribeServiceFacade().findById(new Long(id)).getEntity();
			/**
			 * 换房审核通过 
			 * 1.更新原认购记录第二状态为已换房
			 * 2.生成新的已换房记录
			 * 3.针对已换房记录 已退款
			 * 4.找到新认购记录，增加已收款记录
			 * 5.修改房源状态，原房间 为可售， 新房间为认购
			 * 6.增加房屋变更记录，原房间 认购-可售  新房间 可售到认购
			 * 7.更改异常业务流程的审核状态
			 */
			
			SubscribeDto updateSubscribeDto = new SubscribeDto();
			updateSubscribeDto.setId(new Long(id));
			updateSubscribeDto.setBusinessSecStatus(SubscribeBusinessStatusEnum.HAVEWARDS.getNo());
			//updateSubscribeDto.setCheckDate(new Date());
			getSubscribeServiceFacade().updateByPrimaryKey(updateSubscribeDto, true);
			
			//2.生成已换房记录,修改新认购换房 房间流程为已通过
			SubscribeDto queryDto = new SubscribeDto();
			queryDto.setOldId(new Long(id));
			ResponseList<Subscribe> subscribeList = getSubscribeServiceFacade().findByDto(queryDto);
			if(subscribeList.isSuccess()&&subscribeList.getEntity()!=null){
				Subscribe sourceSubscribe = subscribeList.getEntity().get(0);
				SubscribeDto newSubscibeDto = new SubscribeDto();
				newSubscibeDto.setId(sourceSubscribe.getId());
				newSubscibeDto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
				newSubscibeDto.setCheckDate(new Date());
				newSubscibeDto.setProcInstId(scibe.getProcInstId()); //新认购关联旧流程
				getSubscribeServiceFacade().updateByPrimaryKey(newSubscibeDto, true);
				
				//修改新认购的房间为认购
				ProjectRoomDto newSubRoom = new ProjectRoomDto();
				newSubRoom.setId(sourceSubscribe.getRoomId());
				newSubRoom.setRoomStatus(RoomStatusEnum.BUY.getNo());
				getProjectRoomServiceFacade().updateByDto(newSubRoom);
				
				//修改旧房间为可售
				ProjectRoomDto oldSubRoom = new ProjectRoomDto();
				oldSubRoom.setId(scibe.getRoomId());
				oldSubRoom.setRoomStatus(RoomStatusEnum.VENDIBILITY.getNo());
				getProjectRoomServiceFacade().updateByDto(oldSubRoom);
				
				
				//生成已换房记录
				Subscribe addSourceSub =  getSubscribeServiceFacade().findById(new Long(id)).getEntity();
				addSourceSub.setBusinessStatus(SubscribeBusinessStatusEnum.HAVEWARDS.getNo());
				addSourceSub.setBusinessSecStatus(SubscribeBusinessStatusEnum.HAVEWARDS.getNo());
				SubscribeDto addChange = new SubscribeDto();
				BeanUtil.convert2T(addChange, addSourceSub);
				addChange.setProcInstId(processInstanceId); //已换房流程ID
				addChange.setOldId(new Long(id));
				addChange.setCheckDate(new Date());
				SubscribeDto createSubscribe =  getSubscribeServiceFacade().save(addChange).getEntity();
				//复制原房间的经纪人 
				copyTransactionRelation(new Long(id), createSubscribe.getId());
				//查询原认购 所有的已收款 ， 把已收款 成为 已换房记录的已退款
				Response<BigDecimal> oldSubscribeAmount = gethaveReceiveRefundServiceFacade().findSubscribeHaveAmount(new Long(id));
				//当原认购没有已收款时，不生成待退
				if(oldSubscribeAmount.getEntity()!=null&&oldSubscribeAmount.getEntity().compareTo(BigDecimal.ZERO)!=0){
					//记录应退款记录
					Response<NeedReceiveRefundDto> nrrdSaveResponse = needReceiveRefund(createSubscribe, oldSubscribeAmount.getEntity());
					if(!nrrdSaveResponse.isSuccess()){
		    			throw new Exception(nrrdSaveResponse.getResultMessage());
		    		}
					NeedReceiveRefundDto needDto = nrrdSaveResponse.getEntity();
					Boolean haveFlag = refund(needDto);
					if(!haveFlag){
		    			throw new Exception("自动退款功能执行失败");
		    		}
				}else{
					oldSubscribeAmount.setEntity(BigDecimal.ZERO);
				}
				if(scibe!=null){
					//原认购记录是否有收认购合同金,存在:新记录新增伪签约收款记录
					if(scibe.getTransId()!=null&&scibe.getDepositReceivable().compareTo(oldSubscribeAmount.getEntity())!=0){
						 Signed signed= getSignedById(new Long(id));
						 Response<NeedReceiveRefundDto> signedNeedResponse =  needSignedReceiveRefund(signed, oldSubscribeAmount.getEntity());
						 if(!signedNeedResponse.isSuccess()){
				    			throw new Exception(signedNeedResponse.getResultMessage());
						 }
						 NeedReceiveRefundDto needDto = signedNeedResponse.getEntity();
						 Boolean haveFlag = refund(needDto);
						 if(!haveFlag){
				    			throw new Exception("自动退款功能执行失败");
						 }
						 //查询已售合同金额
					     SubscribeTransRequestDto requestDto = new SubscribeTransRequestDto();
						 requestDto.setSubId(sourceSubscribe.getId());
						 requestDto.setTransAmount(sourceSubscribe.getSubscribeAmount());
						 Response<String>  result =  getsubscribeTransServiceFacade().subcribeTrans(requestDto); 
						 if(StringUtils.isEmpty(result.getEntity())){ //生成新认购的伪签约
							 //伪签约生成成功,多退
							 SubscribeDto needSubscribeDto = new SubscribeDto();
							 BeanUtil.convert2T(needSubscribeDto, sourceSubscribe);
							 if(oldSubscribeAmount.getEntity()!=null&&
									 oldSubscribeAmount.getEntity().compareTo(BigDecimal.ZERO)!=0&&
									 oldSubscribeAmount.getEntity().compareTo(sourceSubscribe.getSubscribeAmount())>0){ //原认购合同金已收金额 大于新认购合同金额
								 	//生成新认购的已收跟已退
								
									BigDecimal needAmount = oldSubscribeAmount.getEntity().subtract(sourceSubscribe.getSubscribeAmount());
									Response<NeedReceiveRefundDto> responseNeedReceive = needReceiveRefund(needSubscribeDto, needAmount);
									if(!responseNeedReceive.isSuccess()){
						    			throw new Exception(responseNeedReceive.getResultMessage());
						    		}
									NeedReceiveRefundDto newSubNeed = responseNeedReceive.getEntity();
									Boolean newSubNeedObj = refund(newSubNeed);
									if(!newSubNeedObj){
						    			throw new Exception("自动退款功能执行失败");
						    		}
									//已收认购金
									haveNeedSource(needSubscribeDto, sourceSubscribe.getDepositReceivable());
									//已收合同金
									haveNeedSubscribe(oldSubscribeAmount.getEntity(), sourceSubscribe.getDepositReceivable(), needSubscribeDto);
									//伪签约的已收  = 新认购合同金-认购金
									Signed subSigned = getSignedById(needSubscribeDto.getId());
									List<NeedReceiveRefund> needSigList = getNeedListBySigId(subSigned);
									if(needSigList!=null){
										Long needId = needSigList.get(0).getId();
										BigDecimal realAmount = needSubscribeDto.getSubscribeAmount().subtract(needSubscribeDto.getDepositReceivable());
										haveSignedReceivefund(needId, subSigned, realAmount);
									}
							 }else{
								  //生成已收
								 BigDecimal convertAmount = oldSubscribeAmount.getEntity()==null?BigDecimal.ZERO:oldSubscribeAmount.getEntity();
								 //认购金已收款
								 if(convertAmount.compareTo(needSubscribeDto.getDepositReceivable())>=0){ //大于
									 haveNeedSource(needSubscribeDto, sourceSubscribe.getDepositReceivable());
									 haveNeedSubscribe(convertAmount, sourceSubscribe.getDepositReceivable(), needSubscribeDto);
									 //伪签约
									 BigDecimal needSigAmount = convertAmount.subtract(needSubscribeDto.getDepositReceivable());
									 Signed subSigned = getSignedById(needSubscribeDto.getId());
									 List<NeedReceiveRefund> needSigList = getNeedListBySigId(subSigned);
									 if(needSigList!=null){
										 haveSignedReceivefund(needSigList.get(0).getId(), signed, needSigAmount);
									 }
								 }
								
							 }
						 }else{
							 throw new Exception(result.getEntity());
						 }
					}else{
						SubscribeDto needSubscribeDto = new SubscribeDto();
						BeanUtil.convert2T(needSubscribeDto, sourceSubscribe);
						//原房间存在认购金,多退少补
						if(sourceSubscribe.getDepositReceivable()==null
								||sourceSubscribe.getDepositReceivable().compareTo(BigDecimal.ZERO)==0
								||oldSubscribeAmount.getEntity().compareTo(sourceSubscribe.getDepositReceivable())>0){
							//需要退款金额
							if(oldSubscribeAmount.getEntity()!=null&&oldSubscribeAmount.getEntity().compareTo(BigDecimal.ZERO)!=0){
								BigDecimal needAmount = null;
								if(sourceSubscribe.getDepositReceivable()==null){
									sourceSubscribe.setDepositReceivable(BigDecimal.ZERO);
								}
								needAmount = oldSubscribeAmount.getEntity().subtract(sourceSubscribe.getDepositReceivable());
								//生成待退款
								Response<NeedReceiveRefundDto> responseNeedReceive = needReceiveRefund(needSubscribeDto, needAmount);
								if(!responseNeedReceive.isSuccess()){
					    			throw new Exception(responseNeedReceive.getResultMessage());
					    		}
								NeedReceiveRefundDto needDto = responseNeedReceive.getEntity();
								Boolean haveFlag = refund(needDto);
								if(!haveFlag){
					    			throw new Exception("自动退款功能执行失败");
					    		}
								SubscribeDto haveSub = new SubscribeDto();
								BeanUtil.convert2T(haveSub, sourceSubscribe);
								haveNeedSource(haveSub, sourceSubscribe.getDepositReceivable());
							}
						}else{
								haveNeedSource(needSubscribeDto, oldSubscribeAmount.getEntity());
						}
					}
					//原房间 状态变更
					RoomChangeHistoryDto changeDto=new RoomChangeHistoryDto();
					changeDto.setRoomId(createSubscribe.getRoomId());
					changeDto.setBusinessDynamics("认购换房");
					changeDto.setBusinessHref("/marketing/businessAbnorma/businessDetail?id="+id);
					changeDto.setRemark("房态由【认购】转为【可售】");
					changeDto.setMerchantId(createSubscribe.getMerchantId());
					changeDto.setAccessCode(createSubscribe.getAccessCode());
					changeDto.setCreateUserId(createSubscribe.getCreateUserId());
					changeDto.setUserCode(createSubscribe.getUserCode());
					changeDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
					changeDto.setUpdateUserId(createSubscribe.getUpdateUserId());
					changeDto.setUpdateTime(Calendar.getInstance().getTime());
					Response<RoomChangeHistoryDto> rchSaveResponse = getRoomChangeHistoryServiceFacade().save(changeDto);
					if(!rchSaveResponse.isSuccess()){
						throw new RuntimeException(rchSaveResponse.getResultMessage());
					}
					
				}
				//新房间 状态变更
				RoomChangeHistoryDto subscibeRoomChange=new RoomChangeHistoryDto();
				subscibeRoomChange.setRoomId(sourceSubscribe.getRoomId());
				subscibeRoomChange.setBusinessDynamics("认购");
				subscibeRoomChange.setBusinessHref("/customer/subscribe/toView?id="+sourceSubscribe.getId());
				subscibeRoomChange.setRemark("房态由【可售】转为【认购】");
				subscibeRoomChange.setMerchantId(sourceSubscribe.getMerchantId());
				subscibeRoomChange.setAccessCode(sourceSubscribe.getAccessCode());
				subscibeRoomChange.setCreateUserId(sourceSubscribe.getCreateUserId());
				subscibeRoomChange.setUserCode(sourceSubscribe.getUserCode());
				subscibeRoomChange.setDelFlag(DelFlagEnum.UNDEL.getNo());
				subscibeRoomChange.setUpdateUserId(sourceSubscribe.getUpdateUserId());
				subscibeRoomChange.setUpdateTime(Calendar.getInstance().getTime());
				Response<RoomChangeHistoryDto> rchSaveResponse = getRoomChangeHistoryServiceFacade().save(subscibeRoomChange);
				if(!rchSaveResponse.isSuccess()){
					throw new RuntimeException(rchSaveResponse.getResultMessage());
				}
				
				
				queryBusiness= new BusinessAbnormaDto();
				queryBusiness.setBusinessId(new Long(id));
				queryBusiness.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_1.getNo());
				businessAbnormaList = getbusinessAbnormaServiceFacade().findByDto(queryBusiness);
				if(businessAbnormaList.isSuccess()&&businessAbnormaList.getEntity()!=null&&businessAbnormaList.getEntity().size()>0){
					BusinessAbnormaDto updateAbnorma= new BusinessAbnormaDto();
					updateAbnorma.setId(businessAbnormaList.getEntity().get(0).getId());
					updateAbnorma.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
					updateAbnorma.setCheckDate(Calendar.getInstance().getTime()); //审核时间
					getbusinessAbnormaServiceFacade().updateByPrimaryKey(updateAbnorma, true);
				}
				/**
				 * （认购换房审核通过）推送消息到app
				 * @author ny
				 * @param param noticeType 提醒类型, noticeBusinessId 业务主键Id
				 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
				 */
				NoticeEntity noticeEntity = new NoticeEntity();
				noticeEntity.setNoticeBusinessId(Long.valueOf(id));
				noticeEntity.setNoticeType("9");
				noticeEntity.setProcessInstanceId(processInstanceId);
				getSubscribeChangeHouseNoticeFacade().createSubscribeChangeHouseNotice(noticeEntity);
				/**
				 * 推送到渠道
				 */
				getChannelSendHttpMessageService().sendTransaction(newSubscibeDto.getId(), TransTypeEnum.SUBSCRIBE.getNo(), false);
			}
		}else{
			BusinessAbnormaDto queryBusiness= new BusinessAbnormaDto();
			queryBusiness.setBusinessId(new Long(id));
			queryBusiness.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_1.getNo());
			queryBusiness.setAuditStatus(AuditStatusEnum.AUDIT.getNo()); //只获取审核中的流程信息
			ResponseList<BusinessAbnorma> businessAbnormaList = getbusinessAbnormaServiceFacade().findByDto(queryBusiness);
			if(businessAbnormaList.isSuccess()&&businessAbnormaList.getEntity()!=null&&businessAbnormaList.getEntity().size()>0){
				BusinessAbnorma businessAbnorma = businessAbnormaList.getEntity().get(0);
				boolean flag = checkAuditCommit(businessAbnorma);
				if(!flag) {
					throw new Exception(ResponseEnums.RESPONSEENUMS_999999.getName());
				}
			}
			
			SubscribeDto queryDto = new SubscribeDto();
			queryDto.setOldId(new Long(id));
			ResponseList<Subscribe> subscribeList = getSubscribeServiceFacade().findByDto(queryDto);
			if(subscribeList!=null&&subscribeList.getEntity().size()>0){
				SubscribeDto updateDTO  = new SubscribeDto();
				Subscribe updateObj = subscribeList.getEntity().get(0);
				updateDTO.setId(updateObj.getId());
				updateDTO.setAuditStatus(AuditStatusEnum.REJECT.getNo());
				updateDTO.setCheckDate(new Date());
				updateDTO.setProcInstId(processInstanceId);
				getSubscribeServiceFacade().updateByPrimaryKey(updateDTO, true);
			}
			//修改异常业务表状态为已退回
			queryBusiness= new BusinessAbnormaDto();
			queryBusiness.setBusinessId(new Long(id));
			queryBusiness.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_1.getNo());
			businessAbnormaList = getbusinessAbnormaServiceFacade().findByDto(queryBusiness);
			if(businessAbnormaList.isSuccess()&&businessAbnormaList.getEntity()!=null&&businessAbnormaList.getEntity().size()>0){
				BusinessAbnormaDto updateAbnorma= new BusinessAbnormaDto();
				updateAbnorma.setId(businessAbnormaList.getEntity().get(0).getId());
				updateAbnorma.setAuditStatus(AuditStatusEnum.REJECT.getNo());
				updateAbnorma.setCheckDate(Calendar.getInstance().getTime()); //审核时间
				getbusinessAbnormaServiceFacade().updateByPrimaryKey(updateAbnorma, true);
			}
			/**
			 * （认购换房审核不通过）推送消息到app
			 * @author ny
			 * @param param noticeType 提醒类型, noticeBusinessId 业务主键Id
			 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
			 */
			NoticeEntity noticeEntity = new NoticeEntity();
			noticeEntity.setNoticeBusinessId(Long.valueOf(id));
			noticeEntity.setNoticeType("9");
			noticeEntity.setProcessInstanceId(processInstanceId);
			getSubscribeChangeHouseNoticeFacade().createSubscribeChangeHouseNotice(noticeEntity);
		}
	}
	
	
	public List<NeedReceiveRefund> getNeedListBySigId(Signed subSigned){
		NeedReceiveRefundDto reSigFunde = new NeedReceiveRefundDto();
		reSigFunde.setRelationId(subSigned.getId());
		reSigFunde.setBusinessType(BusinessTypeEnum.SIGNED.getNo());
		List<NeedReceiveRefund> needSigList = getneedReceiveRefundServiceFacade().findByDto(reSigFunde).getEntity();
		return needSigList;
	}
	/**
	 * 
	 * haveNeedSubscribe:(收合同金). <br/>
	 *
	 * @author Administrator
	 * @param oldSubscribeAmount
	 * @param depositReceivable
	 * @param needSubscribeDto
	 * @throws Exception
	 * @since JDK 1.6
	 */
	public void haveNeedSubscribe(BigDecimal oldSubscribeAmount,BigDecimal depositReceivable,SubscribeDto needSubscribeDto) throws Exception{
		//待收认购合同金 = 已收金额-认购金 
		BigDecimal heTongAmount = oldSubscribeAmount.subtract(depositReceivable);
		Response<NeedReceiveRefundDto> needSub = subscribeCollectNeedRefund(needSubscribeDto,heTongAmount);
		if(!needSub.isSuccess()){
			throw new Exception(needSub.getResultMessage());
		}
		//已收合同金
		subscribeHaveReceivefund(needSub.getEntity().getId(), needSubscribeDto, heTongAmount);
	}
	/**
	 * 
	 * haveNeedSource:(认购金 待收，已收). <br/>
	 *
	 * @author Administrator
	 * @param subscribe
	 * @param amount
	 * @throws Exception
	 * @since JDK 1.6
	 */
	public void haveNeedSource(SubscribeDto subscribe,BigDecimal amount) throws Exception{
		//生成待收款
		Response<NeedReceiveRefundDto> responseNeedReceive = collectNeedRefund(subscribe);
		if(!responseNeedReceive.isSuccess()){
			throw new Exception(responseNeedReceive.getResultMessage());
		}
		if(amount!=null&&amount.compareTo(BigDecimal.ZERO)!=0){
			NeedReceiveRefundDto needDto = responseNeedReceive.getEntity();
			//生成已收款
			Response<HaveReceiveRefundDto> resHave = haveReceivefund(needDto.getId(), subscribe, amount);
			if(!resHave.isSuccess()){
    			throw new Exception(resHave.getResultMessage());
    		}
		}
	}
	/**
	 * 
	 * haveReceivefund:(已收款). <br/>
	 * @author Administrator
	 * @param needId
	 * @param subscribe
	 * @param realAmount
	 * @return
	 * @since JDK 1.6
	 */
	public Response<HaveReceiveRefundDto> haveReceivefund(Long needId,SubscribeDto subscribe,BigDecimal realAmount){
		HaveReceiveRefundDto haveReceiveRefundDto = new HaveReceiveRefundDto();
		haveReceiveRefundDto.setReceivablesId(needId);
		haveReceiveRefundDto.setReceivablesType(BusinessTypeEnum.SUBSCRIBE.getNo());
		haveReceiveRefundDto.setRelationId(subscribe.getId());
		haveReceiveRefundDto.setRealAmount(realAmount);
		haveReceiveRefundDto.setDeductibleAmount(new BigDecimal("0"));
		haveReceiveRefundDto.setCustomerId(subscribe.getCustomerId());
		haveReceiveRefundDto.setRoomId(subscribe.getRoomId());
		haveReceiveRefundDto.setRemark("收认购金");
		haveReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_3.getNo());//认购金
		haveReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_5.getNo()); //认筹金转认购金(转入)
		haveReceiveRefundDto.setMerchantId(subscribe.getMerchantId());
		haveReceiveRefundDto.setUserCode(subscribe.getUserCode());
		haveReceiveRefundDto.setAccessCode(subscribe.getAccessCode());
		haveReceiveRefundDto.setCreateUserId(subscribe.getCreateUserId());
		haveReceiveRefundDto.setDelFlag("0");
		haveReceiveRefundDto.setDocType("0");
		haveReceiveRefundDto.setTransferStatus("0");
		haveReceiveRefundDto.setReChecked("0");
		haveReceiveRefundDto.setStatementType(Long.parseLong(StatementTypeEnum.TRANSFER.getNo()));
		haveReceiveRefundDto.setStatementDate(new Date());
		Response<HaveReceiveRefundDto> resHave = gethaveReceiveRefundServiceFacade().save(haveReceiveRefundDto);
		return resHave;
	}
	
	public Response<HaveReceiveRefundDto> subscribeHaveReceivefund(Long needId,SubscribeDto subscribe,BigDecimal realAmount){
		HaveReceiveRefundDto haveReceiveRefundDto = new HaveReceiveRefundDto();
		haveReceiveRefundDto.setReceivablesId(needId);
		haveReceiveRefundDto.setReceivablesType(BusinessTypeEnum.SUBSCRIBE.getNo());
		haveReceiveRefundDto.setRelationId(subscribe.getId());
		haveReceiveRefundDto.setRealAmount(realAmount);
		haveReceiveRefundDto.setDeductibleAmount(new BigDecimal("0"));
		haveReceiveRefundDto.setCustomerId(subscribe.getCustomerId());
		haveReceiveRefundDto.setRoomId(subscribe.getRoomId());
		haveReceiveRefundDto.setRemark("收认购合同金");
		haveReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_25.getNo());//认购金
		haveReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_18.getNo()); //认筹金转认购金(转入)
		haveReceiveRefundDto.setMerchantId(subscribe.getMerchantId());
		haveReceiveRefundDto.setUserCode(subscribe.getUserCode());
		haveReceiveRefundDto.setAccessCode(subscribe.getAccessCode());
		haveReceiveRefundDto.setCreateUserId(subscribe.getCreateUserId());
		haveReceiveRefundDto.setDelFlag("0");
		haveReceiveRefundDto.setDocType("0");
		haveReceiveRefundDto.setTransferStatus("0");
		haveReceiveRefundDto.setReChecked("0");
		haveReceiveRefundDto.setStatementType(Long.parseLong(StatementTypeEnum.TRANSFER.getNo()));
		haveReceiveRefundDto.setStatementDate(new Date());
		Response<HaveReceiveRefundDto> resHave = gethaveReceiveRefundServiceFacade().save(haveReceiveRefundDto);
		return resHave;
	}
	
	
	
	
	/**
	 * 
	 * collectNeedRefund:(收认购金). <br/>
	 * @author Administrator
	 * @param subscribe
	 * @return
	 * @since JDK 1.6
	 */
	public Response<NeedReceiveRefundDto> collectNeedRefund(SubscribeDto subscribe){
		NeedReceiveRefundDto needReceiveRefundDto=new NeedReceiveRefundDto();
		needReceiveRefundDto.setRelationId(subscribe.getId());
		needReceiveRefundDto.setBusinessType("1");
		needReceiveRefundDto.setTotalReceivablesAmount(subscribe.getDepositReceivable());
		needReceiveRefundDto.setCustomerId(subscribe.getCustomerId());
		needReceiveRefundDto.setRoomId(subscribe.getRoomId());
		needReceiveRefundDto.setStatus("1");
		needReceiveRefundDto.setPostponedStatus("0");
		needReceiveRefundDto.setDocType("0");
		needReceiveRefundDto.setRemark("认购收款");
		needReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_3.getNo());//认购金
		needReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_5.getNo());
		needReceiveRefundDto.setPostponedStatus("0");
		
		needReceiveRefundDto.setMerchantId(subscribe.getMerchantId());
		needReceiveRefundDto.setUserCode(subscribe.getUserCode());
		needReceiveRefundDto.setAccessCode(subscribe.getAccessCode());
		needReceiveRefundDto.setCreateUserId(subscribe.getCreateUserId());
		needReceiveRefundDto.setDelFlag("0");
		needReceiveRefundDto.setUpdateUserId(subscribe.getUpdateUserId());
		needReceiveRefundDto.setUpdateTime(new Date());
		Response<NeedReceiveRefundDto> nrrdSaveResponse=getneedReceiveRefundServiceFacade().save(needReceiveRefundDto);
		return nrrdSaveResponse;
	}

	public Response<NeedReceiveRefundDto> subscribeCollectNeedRefund(SubscribeDto subscribe,BigDecimal amount){
		NeedReceiveRefundDto needReceiveRefundDto=new NeedReceiveRefundDto();
		needReceiveRefundDto.setRelationId(subscribe.getId());
		needReceiveRefundDto.setBusinessType("1");
		needReceiveRefundDto.setTotalReceivablesAmount(amount);
		needReceiveRefundDto.setCustomerId(subscribe.getCustomerId());
		needReceiveRefundDto.setRoomId(subscribe.getRoomId());
		needReceiveRefundDto.setStatus("1");
		needReceiveRefundDto.setPostponedStatus("0");
		needReceiveRefundDto.setDocType("0");
		needReceiveRefundDto.setRemark("收认购合同金");
		needReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_25.getNo());//认购金
		needReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_18.getNo());
		needReceiveRefundDto.setPostponedStatus("0");
		
		needReceiveRefundDto.setMerchantId(subscribe.getMerchantId());
		needReceiveRefundDto.setUserCode(subscribe.getUserCode());
		needReceiveRefundDto.setAccessCode(subscribe.getAccessCode());
		needReceiveRefundDto.setCreateUserId(subscribe.getCreateUserId());
		needReceiveRefundDto.setDelFlag("0");
		needReceiveRefundDto.setUpdateUserId(subscribe.getUpdateUserId());
		needReceiveRefundDto.setUpdateTime(new Date());
		Response<NeedReceiveRefundDto> nrrdSaveResponse=getneedReceiveRefundServiceFacade().save(needReceiveRefundDto);
		return nrrdSaveResponse;
	}
	
	/**
	 * 
	 * needReceiveRefund:(退认购款). <br/>
	 *
	 * @author Administrator
	 * @param createSubscribe
	 * @param oldSubscribeAmount
	 * @return
	 * @since JDK 1.6
	 */
	public Response<NeedReceiveRefundDto> needReceiveRefund(SubscribeDto createSubscribe,BigDecimal oldSubscribeAmount){
		NeedReceiveRefundDto needReceiveRefundDto=new NeedReceiveRefundDto();
		needReceiveRefundDto.setRelationId(createSubscribe.getId());
		needReceiveRefundDto.setBusinessType("1");
		needReceiveRefundDto.setTotalReceivablesAmount(oldSubscribeAmount); //发生额
		needReceiveRefundDto.setCustomerId(createSubscribe.getCustomerId());
		needReceiveRefundDto.setRoomId(createSubscribe.getRoomId());
		needReceiveRefundDto.setStatus("1");
		needReceiveRefundDto.setPostponedStatus("0");
		needReceiveRefundDto.setDocType("1");
		needReceiveRefundDto.setRemark("退认购款");
		needReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_4.getNo());
		needReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_8.getNo());
		needReceiveRefundDto.setPostponedStatus("0");
		
		needReceiveRefundDto.setMerchantId(createSubscribe.getMerchantId());
		needReceiveRefundDto.setUserCode(createSubscribe.getUserCode());
		needReceiveRefundDto.setAccessCode(createSubscribe.getAccessCode());
		needReceiveRefundDto.setCreateUserId(createSubscribe.getCreateUserId());
		needReceiveRefundDto.setDelFlag("0");
		needReceiveRefundDto.setUpdateUserId(createSubscribe.getUpdateUserId());
		needReceiveRefundDto.setUpdateTime(new Date());
		Response<NeedReceiveRefundDto> nrrdSaveResponse=getneedReceiveRefundServiceFacade().save(needReceiveRefundDto);
		return nrrdSaveResponse;
	}
	public Long businessById(Long id){
		BusinessAbnormaDto babDto = new BusinessAbnormaDto(); 
		babDto.setBusinessId(new Long(id));
		babDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_1.getNo());
		babDto.setOrders(" t.id desc ");
		ResponseList<BusinessAbnorma> busineList = getbusinessAbnormaServiceFacade().findByDto(babDto);
		if(busineList.isSuccess()&&busineList.getEntity()!=null){
			return busineList.getEntity().get(0).getId();
		}
		return null;
	}
	/**
	 * 
	 * refund:(生成退款). <br/>
	 *
	 * @author Administrator
	 * @param dto
	 * @return
	 * @since JDK 1.6
	 */
	private boolean refund(NeedReceiveRefundDto dto){
		User user = ShiroUtil.getCurrentUser();
		HaveReceiveRefundDto entity = new HaveReceiveRefundDto();
		BeanUtils.copyProperties(dto, entity);
		entity.setId(null);
		entity.setReceivablesType(dto.getBusinessType()); // 业务类型
		entity.setRelationId(dto.getRelationId());// 业务ID
		entity.setReceivablesId(dto.getId()); // 应收款ID
		entity.setDeductibleAmount(new BigDecimal("0")); // 抵扣金额
		entity.setTransferStatus("0"); // 转账状态 0 正常 1 已转账
		entity.setOpSource("0");
		entity.setBankAccount("默认工商银行-6221234567890"); // 银行账号  
		entity.setStatementId(1L); // 结算人员
		if(null != user) {
			entity.setStatementId(user.getId()); // 结算人员
		}
		entity.setStatementType(Long.parseLong(StatementTypeEnum.CASH.getNo())); // 结算类型
		entity.setDocType("1"); // 已退款
		entity.setReChecked("0"); // 未复核
		entity.setStatementDate(new Date()); // 结算日期
		boolean flag = gethaveReceiveRefundServiceFacade().addRefund(entity, dto.getId(), new BigDecimal("0"),dto.getTotalReceivablesAmount(), "need");
		return flag;
	}
	
	public Signed getSignedById(Long subId){
		 //生成签约待退款 （原认购伪签约退款）
		 SubscribeTransDto queryTransDto = new SubscribeTransDto();
		 queryTransDto.setSubId(subId);
		 SubscribeTrans trans =  getsubscribeTransServiceFacade().findByDto(queryTransDto).getEntity().get(0);
		 Signed signed =  getSignedServiceFacade().findById(trans.getSigId()).getEntity();
		 return signed;
	}
	/**
	 * 
	 * needSignedReceiveRefund:(退签约金,伪签约). <br/>
	 * @author Administrator
	 * @param signed
	 * @param amount
	 * @return
	 * @since JDK 1.6
	 */
	public Response<NeedReceiveRefundDto> needSignedReceiveRefund(Signed signed ,BigDecimal amount){
		NeedReceiveRefundDto needReceiveRefundDto=new NeedReceiveRefundDto();
		needReceiveRefundDto.setRelationId(signed.getId());
		needReceiveRefundDto.setBusinessType("2");
		needReceiveRefundDto.setTotalReceivablesAmount(amount); //发生额
		needReceiveRefundDto.setCustomerId(signed.getCustomerId());
		needReceiveRefundDto.setRoomId(signed.getRoomId());
		needReceiveRefundDto.setStatus("1");
		needReceiveRefundDto.setPostponedStatus("0");
		needReceiveRefundDto.setDocType("1");
		needReceiveRefundDto.setRemark("退签约金(认购收取签约金)");
		needReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_21.getNo());
		needReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_14.getNo());
		needReceiveRefundDto.setPostponedStatus("0");
		
		needReceiveRefundDto.setMerchantId(signed.getMerchantId());
		needReceiveRefundDto.setUserCode(signed.getUserCode());
		needReceiveRefundDto.setAccessCode(signed.getAccessCode());
		needReceiveRefundDto.setCreateUserId(signed.getCreateUserId());
		needReceiveRefundDto.setDelFlag("0");
		needReceiveRefundDto.setUpdateUserId(signed.getUpdateUserId());
		needReceiveRefundDto.setUpdateTime(new Date());
		Response<NeedReceiveRefundDto> nrrdSaveResponse=getneedReceiveRefundServiceFacade().save(needReceiveRefundDto);
		return nrrdSaveResponse;
	}
	
	/**
	 * 
	 * haveSignedReceivefund:(签约合同金). <br/>
	 *
	 * @author Administrator
	 * @param needId
	 * @param signed
	 * @param realAmount
	 * @return
	 * @since JDK 1.6
	 */
	public Response<HaveReceiveRefundDto> haveSignedReceivefund(Long needId,Signed signed,BigDecimal realAmount){
		HaveReceiveRefundDto haveReceiveRefundDto = new HaveReceiveRefundDto();
		haveReceiveRefundDto.setReceivablesId(needId);
		haveReceiveRefundDto.setReceivablesType(BusinessTypeEnum.SIGNED.getNo());
		haveReceiveRefundDto.setRelationId(signed.getId());
		haveReceiveRefundDto.setRealAmount(realAmount);
		haveReceiveRefundDto.setDeductibleAmount(new BigDecimal("0"));
		haveReceiveRefundDto.setCustomerId(signed.getCustomerId());
		haveReceiveRefundDto.setRoomId(signed.getRoomId());
		haveReceiveRefundDto.setRemark("认购合同金");
		haveReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_25.getNo());//认购金
		haveReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_13.getNo()); //认筹金转认购金(转入)
		haveReceiveRefundDto.setMerchantId(signed.getMerchantId());
		haveReceiveRefundDto.setUserCode(signed.getUserCode());
		haveReceiveRefundDto.setAccessCode(signed.getAccessCode());
		haveReceiveRefundDto.setCreateUserId(signed.getCreateUserId());
		haveReceiveRefundDto.setDelFlag("0");
		haveReceiveRefundDto.setDocType("0");
		haveReceiveRefundDto.setTransferStatus("0");
		haveReceiveRefundDto.setReChecked("0");
		haveReceiveRefundDto.setStatementType(Long.parseLong(StatementTypeEnum.TRANSFER.getNo()));
		haveReceiveRefundDto.setStatementDate(new Date());
		Response<HaveReceiveRefundDto> resHave = gethaveReceiveRefundServiceFacade().save(haveReceiveRefundDto);
		return resHave;
	}
	/**
	 * 
	 * copyTransactionRelation:(将原认购的经纪人复制到已换房记录下). <br/>
	 *
	 * @author Administrator
	 * @param oldSubId
	 * @param newSubId
	 * @since JDK 1.6
	 */
	public void copyTransactionRelation(Long oldSubId,Long newSubId){
		TransactionRelationDto tranDto = new TransactionRelationDto();
		tranDto.setBusinessId(oldSubId);
		tranDto.setRelationType("5");
		tranDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
		ResponseList<TransactionRelation> transList = getTransactionRelationServiceFacade().findByDto(tranDto);
		if(transList.isSuccess()&&transList.getEntity()!=null&&transList.getEntity().size()>0){
			for (TransactionRelation trans:transList.getEntity()) {
				TransactionRelationDto addRelation = new TransactionRelationDto();
				BeanUtil.convert2T(addRelation, trans);
				addRelation.setBusinessId(newSubId);
				getTransactionRelationServiceFacade().save(addRelation);
			}
		}
	}
	
	
	/**
	 * 前置判断,审核记录是否已经提交,防止重复提交
	 * 产生原因: 提交审核,后台处理中时,刷新页面再次提交审核,会重复
	 * true: 可继续执行
	 * false: 不可执行
	 */
	public boolean checkAuditCommit(BusinessAbnorma entity) {
		// 业务数据为null时,默认通过.为了不改变老业务,不影响流程正常行走
		if (null == entity) {
			return true;
		}
		return getActcommitLogService().checkActCommit(entity.getAuditStatus(), entity.getMerchantId(), entity.getId(),
				entity.getProcInstId(), "认购换房", "PC");
	}
	
	private ActCommitLogService getActcommitLogService(){
		return (ActCommitLogService)SpringWebContextUtil.getApplicationContext().getBean("actCommitLogService");
	}
	
	private SubscribeChangeHouseNoticeFacade getSubscribeChangeHouseNoticeFacade(){
		return (SubscribeChangeHouseNoticeFacade)SpringWebContextUtil.getApplicationContext().getBean("subscribeChangeHouseNoticeFacade");
	}
	
	private ActivitiProcessServiceImpl getActivitiProcessServiceImpl(){
		return (ActivitiProcessServiceImpl)SpringWebContextUtil.getApplicationContext().getBean("activitiProcessServiceImpl");
	}
	
	private SubscribeServiceFacade getSubscribeServiceFacade(){
		return (SubscribeServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("subscribeServiceFacade");
	}
	
	private BusinessAbnormaServiceFacade getbusinessAbnormaServiceFacade(){
		return (BusinessAbnormaServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("businessAbnormaServiceFacade");
	}
	private HaveReceiveRefundServiceFacade gethaveReceiveRefundServiceFacade(){
		return (HaveReceiveRefundServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("haveReceiveRefundServiceFacade");
	}
	private NeedReceiveRefundServiceFacade getneedReceiveRefundServiceFacade(){
		return (NeedReceiveRefundServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("needReceiveRefundServiceFacade");
	}
	
	private SubscribeTransServiceFacade getsubscribeTransServiceFacade(){
		return (SubscribeTransServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("subscribeTransServiceFacade");
	}
	
	private SignedServiceFacade getSignedServiceFacade(){
		return (SignedServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("signedServiceFacade");
	}
	
	private RoomChangeHistoryServiceFacade getRoomChangeHistoryServiceFacade(){
		return (RoomChangeHistoryServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("roomChangeHistoryServiceFacade");
	}
	
	private TransactionRelationServiceFacade getTransactionRelationServiceFacade(){
		return (TransactionRelationServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("transactionRelationServiceFacade");
	}
	private ProjectRoomServiceFacade getProjectRoomServiceFacade(){
		return (ProjectRoomServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("projectRoomServiceFacade");
	}

	private ChannelSendHttpMessageService getChannelSendHttpMessageService(){
		return (ChannelSendHttpMessageService)SpringWebContextUtil.getApplicationContext().getBean("channelSendHttpMessageService");
	}
	
}
